[t:/]$ 지식_

참고 : timer3를 측정용으로 사용하기

2012/08/26
s5pc100 pwm timer 3번을 시간 측정용으로 쓰기.

u-boot.1.3.4 기준.
최신 u-boot 는 구조가 대폭적으로 바뀌었음.

/lib_arm/board.c

#include  // 헤더 까서 timer 3 번 레지스터 정의가 없다면 데이터 시트 보고 때려넣을 것

다음 함수를 추가하자. 모양은 이쁘게 알아서 바꾸삼..;;

// _dawnsea_
// unsigned int my_max;
static int setup_timer3(void)
{
TCFG1_REG = (TCFG1_REG & ~((0xf) 

// 해당 부위 찾아서 setup_timer3 펑션포인터 추가할 것.. 부팅하면서 알아서 순차 실행할 것임..
// setup_timer3 호출 순간 타이머 발싸! 그 이전은 알 수 없는 것임.. 사실은 더 있지만 일단 생략..

init_fnc_t *init_sequence[] = {
cpu_init,               /* basic cpu dependent setup */
#if defined(CONFIG_SKIP_RELOCATE_UBOOT)
reloc_init,             /* Set the relocation done flag, must
do this AFTER cpu_init(), but as soon
as possible */
#endif
setup_timer3,
board_init,             /* basic board dependent setup */
interrupt_init,         /* set up exceptions */
env_init,               /* initialize environment */

init_baudrate,          /* initialze baudrate settings */
serial_init,            /* serial communications setup */
console_init_f,         /* stage 1 init of console */
print_timer3, // 이 함수 호출 될 때 시간 찍히니까 유심히 보도록..
...

display_banner 함수 찾아서 타이머 정확한 지 테스트 해보자.

#if 0 // dawnsea 타이머 정확도 측정용. 현재 정확함
for (i = 0; i 

U-Boot에 뻘짓해 놓지 않았다면 1초마다 값이 출력될 것임.. 계산이 틀리면 보통 0.5초. 0.1초. 2초. 4초 이렇게 틀어짐..

이렇게 해서 U-Boot 안에서 시간을 볼 수 있고.. timer3는 커널에서 건들지 않응께.. 커널이 개시되도 시간은 흐른당..

이제 커널에서 시간을 찍어보자. 아 시각이 맞겠네 시각..

대충.. static noinline int init_post(void) 함수에 박아봅시다..
이제부터는 산수의 시간..

만약 해당 레지스터를 못 찾겠다면 관련 헤더를 잘 디벼봅시다.
데이터시트에 있는 레지스터 주소 값을 찾은 후.. 바로 쓰면 안 됨.. 가상주소로 사용하기 위해 특정 값을 더해서 쓰던가..
아예 가상주소를 이용해서 헤더파일이 존재할 것임..

....
(void) sys_dup(0);
(void) sys_dup(0);

current->signal->flags |= SIGNAL_UNKILLABLE;

if (ramdisk_execute_command) {
run_init_process(ramdisk_execute_command);
printk(KERN_WARNING "Failed to execute %s\n",
ramdisk_execute_command);
}

/*
* We try each of these until one succeeds.
*
* The Bourne shell can be used instead of init if we are
* trying to recover a really broken machine.
*/
// 현재 카운터가 나타내는 시간이다.. S3C_VA_TIMER 값이 제대로 정의되어 있는지 확인 할 것..
// 모르겠으면 데이터 시트 디벼볼 것..
printk("CT1 = %ld\n", 1000000 - *(unsigned int *)(S3C_VA_TIMER + 0x38) / 2063L);
if (execute_command) {
run_init_process(execute_command);
printk(KERN_WARNING "Failed to execute %s.  Attempting "
"defaults...\n", execute_command);
}

printk("CT2 = %ld\n", 1000000 - *(unsigned int *)(S3C_VA_TIMER + 0x38) / 2063L);

에휴.. 커널 압축 해제 시간 구해보자..

/arch/arm/boot/compressed/misc.c

// 부팅 극초반이라 printk가 동작하지 않음을 유의..

ulg
decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p,
int arch_id)
{
unsigned int mytime; // dawnsea
output_data             = (uch *)output_start;  /* Points to kernel start */
free_mem_ptr            = free_mem_ptr_p;
free_mem_end_ptr        = free_mem_ptr_end_p;
__machine_arch_type     = arch_id;

arch_decomp_setup();

mytime = *(unsigned long *)(0xEA000038);  // 타이머3번 카운터 값 레지스터의 버쳘 주소임..

putstr("tick = ");
put_i(mytime);
putstr("  ");
put_i(0xAABBCCDD);   // 괜히 찍어본 이유는 엔디안 틀어지고 뒤죽박죽 됐을까봐 눈으로 확인..
putc('\n');

makecrc();
putstr("\nUncompressing Linux...");
gunzip();
putstr(" done, booting the kernel.\n");

mytime = *(unsigned long *)(0xEA000038);

putstr("tick = ");
put_i(mytime);
putstr("  ");
put_i(0xAABBCCDD);
putc('\n');

return output_ptr;
}

한 번 해봤으니 이제 부트차트나 좀 제대로 된 프로파일러를 써봅시다.. 이게 뭐냐고..

http://lxr.free-electrons.com/source/t ··· hart.txt

하지만 부팅 극초반을 다루진 않는 듯..





공유하기













[t:/] is not "technology - root". dawnsea, rss